package edu.washington.cs.workflow.spec4j.example;

import java.util.Collection;

import org.uispec4j.Button;
import org.uispec4j.Panel;
import org.uispec4j.Table;
import org.uispec4j.Trigger;
import org.uispec4j.UIComponent;
import org.uispec4j.UISpec4J;
import org.uispec4j.UISpecTestCase;
import org.uispec4j.Window;
import org.uispec4j.finder.ComponentMatcher;
import org.uispec4j.interception.MainClassAdapter;
import org.uispec4j.interception.WindowHandler;
import org.uispec4j.interception.WindowInterceptor;
import org.uispec4j.interception.handlers.ModalInterceptionCheckerHandler;
import org.uispec4j.interception.handlers.NewThreadInterceptionHandlerDecorator;
import org.uispec4j.interception.handlers.ShownInterceptionCollectorHandler;
import org.uispec4j.interception.handlers.ShownInterceptionDetectionHandler;
import org.uispec4j.interception.toolkit.UISpecDisplay;
import org.uispec4j.utils.TriggerRunner;

import edu.washington.cs.workflow.analysis.guistructure.EventSequence;
import edu.washington.cs.workflow.analysis.guistructure.EventSequenceReplayer;
//import edu.washington.cs.workflow.analysis.guistructure.MonkeyTestingMain;
import edu.washington.cs.workflow.analysis.guistructure.SequenceExecutionOutcome;
import edu.washington.cs.workflow.analysis.guistructure.Spec4JUtils;
import edu.washington.cs.workflow.analysis.guistructure.uievents.UIEvent.WINDOW;

public class TestAddressbook extends UISpecTestCase {
	static {
        UISpec4J.init();
    } 
	
	protected void setUp() throws Exception {
	    setAdapter(new MainClassAdapter(samples.addressbook.main.Main.class, new String[0]));
	}
	
	public void testCreatingAContact() throws Exception {
		  // 1. Retrieve the components
		  Window window = getMainWindow();
		  
		  System.out.println(window.getDescription());
		  
		  UIComponent[] uis = window.getUIComponents(ComponentMatcher.ALL);
		  System.out.println(uis.length);
		  for(UIComponent ui : uis) {
			  if(ui != null) {
				  System.out.println();
				  System.out.println(ui.getClass());
			      System.out.println("   " + ui.getName());
			      System.out.println("   " + ui.getDescription());
			  }
		  }
		  
		  
		  Table table = window.getTable();
		  
		  Button newContactButton = window.getButton("New contact");
		  System.out.println(newContactButton.getLabel());
		  System.out.println(newContactButton.getDescription());

		  // 2. Check that the contacts table is empty and displays
		  // the proper column names
		  assertTrue(table.getHeader().contentEquals(new String[]{
		    "First name", "Last name", "E-mail", "Phone", "Mobile"
		  }));
		  assertTrue(table.isEmpty());

		  // 3. Click on the "New contact" button and check that an
		  // empty row is displayed in the contacts table
		  newContactButton.click();
		  assertTrue(table.contentEquals(new String[][]{
		    {"", "", "", "", ""}
		  }));
		  assertTrue(table.rowIsSelected(0));
		  
		  
		  System.out.println(window.getTextBox("first").getText());
		  System.out.println(window.getTextBox("last").getText());
		  System.out.println(window.getTextBox("E-mail").getText());
		  System.out.println(window.getTextBox("phone").getText());
		  //window.getTextBox("mobile").setText("xx", true);
		  
//		  window.getInputTextBox("first").setText("aa");
//		  System.out.println(window.getInputTextBox("first").getText());
		  
		  // 4. Change the fields of the created empty contact and check
		  // that the contacts table is updated accordingly
		  window.getInputTextBox("first").setText("Homer");
		  window.getInputTextBox("last").setText("Simpson");
		  window.getInputTextBox("field:E-mail").setText("homer@simpson.com");
		  window.getInputTextBox("phone").setText("012345");
		  window.getInputTextBox("mobile").setText("242424");
		  assertTrue(table.contentEquals(new String[][]{
		    {"Homer", "Simpson", "homer@simpson.com", "012345", "242424"}
		  }));
		}
	
	public void testDoubleclick() {
		Window window = getMainWindow();
		window.getButton("New Category").click();
		window.getButton("New Category").click();
		window.getButton("New Category").click();
		window.getButton("New Category").click();
		
//		window.getInputTextBox("first").tri
	}
	
	public void testErrorRevealing() {
		Window window = getMainWindow();
		window.getButton("New contact").click();
		window.getTextBox("field:Mobile").setText("oaYph,,;,S");
		window.getTextBox("field:E-mail").setText("RHW$?qwyRQ");
		window.getTextBox("field:First name").setText("B(^9idr1Ha");
		window.getTable().doubleClick(1, 3);
		
		WINDOW winStatus = Spec4JUtils.getTriggeredDialog(window.getTable(), window.getTable().triggerRightClick(1, 0));
		System.out.println(winStatus);
		
		window.getTable().rightClick(1, 0); 
	}
	
	public void testTreeClick() {
		Window window = getMainWindow();
		window.getTree().click("");
	}
	
	public void testCreateCategories() {
//		UISpec4J.setWindowInterceptionTimeLimit(10000);
		Window window = getMainWindow();
		System.out.println(window.getDescription());
		  createCategory(window, "", "friends");
		  createCategory(window, "", "work");
		  createCategory(window, "work", "design-up");
//		  System.out.println(window.getTree().con);
		  System.out.println(window.getTree().toString());
		  assertTrue(window.getTree().contentEquals("All\n" +
		    "  friends\n" +
		    "  work\n" +
		    "    design-up\n\n"));
		  
		  window.getTree().click("work/design-up");
	}
	
	protected void createCategory(Window window, String parentCategoryPath, final String categoryName) {
		  window.getTree().select(parentCategoryPath);
		  
		  Button b = window.getButton("New Category");
		  Trigger t = b.triggerClick();
		  System.out.println(t.toString());
		  
		  //WindowInterceptor.run(t);
		  
//		  Spec4JUtils.setUseCache(true);
		  System.out.println(Spec4JUtils.getTriggeredDialog(b, t));
		  
		  WindowInterceptor.init(t)
		  .process(new WindowHandler() {
		    public Trigger process(Window dialog) {
		      assertTrue(dialog.titleEquals("Create a category"));
		      dialog.getInputTextBox().setText(categoryName);
		      
		      System.out.println("before pressing: " + dialog.isVisible().isTrue());
		      dialog.getButton("Cancel").click();
		      System.out.println("after pressing: " + dialog.isVisible().isTrue());
		      dialog.getButton("Cancel").click();
		      System.out.println("after pressing: " + dialog.isVisible().isTrue());
		      
//		      Trigger t = dialog.getButton("OK").triggerClick();
		      
		      return dialog.getButton("OK").triggerClick();
		    }
		  })
		  .run();
		}
	
//	public void testAddressBook() {
//		MonkeyTestingMain.main(new String[]{"samples.addressbook.main.Main"});
//	}
	
//	public void testAddressBookReplay() {
//		//must init the environment
//		UISpec4J.init();
//		
////		Spec4JUtils.setUseCache(true);
//		
////		String adapterClassName = System.getProperty("uispec4j.adapter");
////		System.out.println(adapterClassName);
//		
//		MonkeyTestingMain tester = new MonkeyTestingMain("samples.addressbook.main.Main", new String[]{});
//		tester.setIterations(10);
//		
//		Collection<EventSequence> seqs = tester.doMonkeyTesting();
//		
//		System.out.println("generated sequences: " + seqs.size());
//		int num = 1;
//		for(EventSequence seq : seqs) {
//			System.out.println("//////////////////");
//			System.out.println("The " + (num++) + "-th sequence: ");
//			System.out.println(seq.toString());
//			System.out.println();
//		}
//		
//		int index = 1;
//		for(EventSequence seq : seqs) {
//			System.out.println("The " + (index++) + "-th sequence: ");
//			System.out.println(seq.toString());
//			if(!seq.getEventList().isEmpty()) {
//				System.out.println("++++ find one for replay, length: " + seq.getEventList().size() + ", #" + index);
//				
////				UISpec4J.init();
////				MonkeyTestingMain m = new MonkeyTestingMain("samples.addressbook.main.Main", new String[]{});
////				m.setUpEnv();
//				
//				Panel mainWindow = tester.getFreshMainWindow();
//				
//				System.out.println("^^^^ Get a new window");
//				System.out.println(mainWindow.getDescription());
//				System.out.println(System.identityHashCode(mainWindow));
//				EventSequenceReplayer replayer = new EventSequenceReplayer(seq, mainWindow);
//				SequenceExecutionOutcome outcome = replayer.replay();
////				System.out.println(outcome.getActivePanels());
//				System.out.println("Active panel#: " + outcome.getActivePanels().size());
//				for(Panel p : outcome.getActivePanels()) {
//					System.out.println("   " + ((Window)p).getTitle());
//				}
//			}
//		}
//	}
}
